using Engine.Graphics;
using SharpDX;
using System;
using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;

namespace WpfModelViewer
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        #region Private Fields

        private Engine.Camera.Camera camera;
        private Int32Rect completeScreenSize;
        private Engine.Engine engine;
        private MaterialManager materialManager;
        private Engine.FileFormats3D.Wr2Scenario scenery;
        private ShaderManager shaderManager;

        #endregion Private Fields

        #region Public Constructors

        public Window1()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(Window_Loaded);
        }

        #endregion Public Constructors

        #region Private Methods

        /// <summary>
        /// Device Reset Test
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            this.d3dimage.Lock();
            this.d3dimage.Unlock();
            this.camera.MoveForward(-10.0f);
        }

        private void InitializeD3D()
        {
            MessageBox.Show("init start");
            String appStartPath = System.IO.Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);

            HwndSource hwnd = new HwndSource(0, 0, 0, 0, 0, "test", IntPtr.Zero);
            this.camera = new Engine.Camera.Camera();
            this.camera.TargetPosition = Vector3.Zero;
            this.camera.Position = new Vector3(0, 1000, 1);
            this.engine = new Engine.Engine(this, hwnd, camera);
            this.materialManager = new MaterialManager(this.engine, appStartPath + "\\Texture\\");
            this.shaderManager = new ShaderManager(this.materialManager, appStartPath + "\\shaders\\", this.engine.Device);
            this.engine.AddShaderManager(this.shaderManager);
            this.engine.Grafic.Camera = this.camera;
            this.engine.Grafic.ClearColor = System.Drawing.Color.White;

            CompositionTarget.Rendering += OnRendering;

            this.shaderManager.SetSunColor(new Color4(0.0f, 0.25f, 0.25f, 0.25f));

            completeScreenSize.Height = d3dimage.PixelHeight;
            completeScreenSize.Width = d3dimage.PixelWidth;
            //////////SharpDX.DXGI.Surface renderTexture = new SharpDX.DXGI.Surface();
            d3dimage.Lock();
            //////////var surface = renderTexture.GetSurfaceLevel(0);
            //////////d3dimage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, surface.ComPointer);
            //////////var rect = Int32Rect(0, 0, width, height);
            //////////d3dimage.AddDirtyRect(rect);
            d3dimage.Unlock();

            //this.engine.Grafic.SetBackbufferSize((int)output.RenderSize.Height, (int)output.RenderSize.Width);
            //this.engine.Grafic.SetBackbufferSize(d3dimage.PixelHeight, d3dimage.PixelWidth);
            completeScreenSize.Height = d3dimage.PixelHeight;
            completeScreenSize.Width = d3dimage.PixelWidth;
        }

        private void LoadWR2Scenery()
        {
            string sceneryDirectory = @"E:\Games\World Racing 2\Scenarios\546454";
            sceneryDirectory = @"E:\Games\World Racing 2\Scenarios\Italien";

            if (!Directory.Exists(sceneryDirectory))
                sceneryDirectory = @"C:\Games\World Racing 2\Scenarios\Italien";

            if (Directory.Exists(sceneryDirectory))
            {
                scenery = new Engine.FileFormats3D.Wr2Scenario(sceneryDirectory, this.engine, this.shaderManager, this.camera, 100000);
                this.engine.Grafic.AddRenderableObjects(scenery, 1);

                MessageBox.Show("Sceneario geladen!");
            }
            else
                MessageBox.Show("Kein Sceneario geladen!");
        }

        private void OnIsFrontBufferAvailableChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (d3dimage.IsFrontBufferAvailable)
            {
                InitializeD3D();
                //CompositionTarget.Rendering += OnRendering;
                //d3dimage.IsFrontBufferAvailableChanged += new DependencyPropertyChangedEventHandler(OnIsFrontBufferAvailableChanged);

                d3dimage.Lock();
                //d3dimage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, this.engine.Grafic.Device.GetBackBuffer(0, 0).ComPointer);
                d3dimage.Unlock();
            }
            else
            {
                CompositionTarget.Rendering -= OnRendering;
            }
        }

        private void OnRendering(object sender, EventArgs e)
        {
            Result result;
            RenderingEventArgs args = (RenderingEventArgs)e;

            //this.engine.Grafic.ClearColor = System.Drawing.Color.FromArgb(128, 128, 128, 128);
            try
            {
                if (d3dimage.IsFrontBufferAvailable)
                {
                    //this.camera.TargetPosition = Vector3.Zero;
                    if (this.engine.Mouse.ButtonL)
                        this.camera.RotateCameraAroundTarget(-this.engine.Mouse.AxisX, -this.engine.Mouse.AxisY);

                    if (this.engine.Keyboard.forword)
                        this.camera.MoveForward(100.0f);
                    if (this.engine.Keyboard.rewind)
                        this.camera.MoveForward(-100.0f);
                    this.engine.Update();
                    this.engine.Grafic.Camera = this.camera;

                    //result = this.engine.Grafic.Device.TestCooperativeLevel();

                    //if (result.IsFailure)
                    //{
                    //    throw new Direct3D9Exception();
                    //}
                    //IntPtr pSurface = this.engine.Grafic.Device.GetBackBuffer(0, 0).ComPointer;
                    //if (pSurface != IntPtr.Zero)
                    //{
                    //    d3dimage.Lock();
                    //    d3dimage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, pSurface);

                    //    this.engine.Grafic.SetupMatricesAndShaderValues();
                    //    this.engine.Grafic.Render();
                    //    d3dimage.AddDirtyRect(this.completeScreenSize);
                    //    d3dimage.Unlock();
                    //}
                }
            }
            catch (Exception ex)
            {
                string msg = ex.Message;

                InitializeD3D();
                //CompositionTarget.Rendering += OnRendering;
                //d3dimage.IsFrontBufferAvailableChanged += new DependencyPropertyChangedEventHandler(OnIsFrontBufferAvailableChanged);

                d3dimage.Lock();
                //d3dimage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, this.engine.Grafic.Device.GetBackBuffer(0, 0).ComPointer);
                d3dimage.Unlock();
            }
        }

        private void output_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (this.engine != null && this.engine.Grafic != null)
            {
                //this.engine.Grafic.SetBackbufferSize((int)output.RenderSize.Height, (int)output.RenderSize.Width);
                d3dimage.Lock();
                //d3dimage.SetBackBuffer(
                //  D3DResourceType.IDirect3DSurface9,
                //  this.engine.Grafic.Device.GetBackBuffer(0, 0).ComPointer
                //  );
                completeScreenSize.Height = d3dimage.PixelHeight;
                completeScreenSize.Width = d3dimage.PixelWidth;

                d3dimage.Unlock();
            }
        }

        private void Window_DragEnter(object sender, DragEventArgs e)
        {
        }

        private void Window_DragLeave(object sender, DragEventArgs e)
        {
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            InitializeD3D();
            //LoadWR2Scenery();
            return;
        }

        private void Window_LocationChanged(object sender, EventArgs e)
        {
            if (TaskbarItemInfo == null)
            {
                TaskbarItemInfo = new System.Windows.Shell.TaskbarItemInfo();
                TaskbarItemInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Normal;
            }

            TaskbarItemInfo.ProgressValue -= 0.001;
            if (TaskbarItemInfo.ProgressValue <= 0)
                TaskbarItemInfo.ProgressValue = 100;
            TaskbarItemInfo.ProgressValue -= 0.001;
        }

        #endregion Private Methods
    }
}